package chapter

object Chapter12 extends App {

  //1  values(x => x*x,-5,5) result=(-5,25),(-4,16).....(5,25)
  def values(fun: (Int) => Int, low: Int, hight: Int) =
    for (i <- low to hight) yield Pair(i, fun(i)) //Pair  def apply[A, B](x: A, y: B) = Tuple2(x, y)

  println(values(x => x * x, -5, 5))

  //2 
  def aryMax(array: Iterable[Int]) = array reduceLeft ((x, y) => if (x > y) x else y)
  println(aryMax(Array(9, 3, 4, 6)))

  //3
  def fact(toNum: Int) = if (toNum < 1) 1 else (1 to toNum) reduceLeft (_ * _)
  println(fact(2))

  //4
  def fact4(num: Int) = (1 to num).foldLeft(1)(_ * _)

  //5
  def largest(fun: (Int) => Int, inputs: Seq[Int]) = inputs.map(fun).max
  assert(largest(x => 10 * x - x * x, 1 to 10) == 25)

  //6
  def largest2(fun: (Int) => Int, inputs: Seq[Int]) = inputs.map(i => (i, fun(i))).reduceLeft((x, y) => if (x._2 > y._2) x else y)._1
  assert(largest2(x => 10 * x - x * x, 1 to 10) == 5)

  //7
  def adjustToPair(fun: (Int, Int) => Int)(pair: (Int, Int)) = fun(pair._1, pair._2)
  //8
  def func8(strs: Seq[String], lengths: Seq[Int]) =
    strs.corresponds(lengths)(_.length == _)

  //9  def corresponds[B](that: GenSeq[B])(p: (A,B) => Boolean): Boolean 

  def corresponds2[A, B](thi: Seq[A], that: Seq[B], p: (A, B) => Boolean): Boolean = {
    def toPair[T](fun: (A, B) => T)(pair: (A, B)) = fun(pair._1, pair._2)
    (thi zip that).map(toPair(p) _).reduceLeft(_ && _)
  }

  //10
  def unless(condition: => Boolean)(doFn: => Unit) = if (condition) doFn
}